/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include <Context/当前默认操作数据.h>
#include <core/引擎配置.h>
#include "core/shader_line.h"

#include "数据创建销毁.h"
#include "节点编辑.h"


static S_Mesh* g圆圈线 = nullptr;
static S_Mesh* g包围盒 = nullptr;

static S_Mesh* g虚拟体边界线 = nullptr;
static S_Mesh* g虚拟体中心圆 = nullptr;
static S_Mesh* g虚拟体方向线 = nullptr;
static S_Mesh* g虚拟体发光面 = nullptr;

static S_Mesh* g单元素虚拟体网格 = nullptr;


static S_VkDrawIndirectCommand g虚拟体中心Indirect = {};
static S_VkDrawIndirectCommand g虚拟体中心_摄像机锥形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体中心_立方体Indirect = {};

static S_VkDrawIndirectCommand g虚拟体XY圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体YZ圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体XZ圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体XZ缩放圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体XYZ圆形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体方向Indirect = {};
static S_VkDrawIndirectCommand g虚拟体锥形Indirect = {};
static S_VkDrawIndirectCommand g虚拟体边界线_并排线Indirect = {};
static S_VkDrawIndirectCommand g虚拟体边界线_XY四边形Indirect = {};

static S_VkDrawIndirectCommand g虚拟体四边Indirect = {};
static S_VkDrawIndirectCommand g虚拟体方向线_Z_Indirect = {};
static S_VkDrawIndirectCommand g虚拟体方向线_Y三角箭头_Indirect = {};


static S_VkDrawIndirectCommand gIndirect单元素虚拟体_XY圆 = {};
static S_VkDrawIndirectCommand gIndirect单元素虚拟体_XZ圆 = {};
static S_VkDrawIndirectCommand gIndirect单元素虚拟体_圆柱 = {};
static S_VkDrawIndirectCommand gIndirect单元素虚拟体_平面 = {};



static S_物体* g单虚拟体主物体 = nullptr;


static std::list<S_单色材质包>	g_骨骼材质包;
static std::list<S_材质管线*>		g_VecSphere质包;

static S_VkDrawIndirectCommand Indirect_立方体 = {};





S_物体* f_node_初始化单虚拟体网格(S_设备环境& ctx) {
	if(!g包围盒) {
		g包围盒 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
		g包围盒->m_网格类型 = E_绘制方式::e_画线段;
		g包围盒->m_线宽 = 1.0;

		uint32 offset = 0;
		std::vector<S_VC> 顶点;
		
		{
			Indirect_立方体 = { 24, 1, offset, 0 };
			Indirect_立方体.vertexCount = f_graph_立方体线段(顶点, {1,1,1}, {}, S_RGBA8UI{0,0,0,255});
			Indirect_立方体.firstVertex = offset;
			offset += Indirect_立方体.vertexCount;
		}

		{

		}

		f_mesh_fill顶点数据(g包围盒, 顶点);
	}

	g单虚拟体主物体 = f_ob_创建(ctx, E_物体类型::t_虚拟体);
	f_ob_set数据槽数量(g单虚拟体主物体, 1);
	f_ob_set数据(g单虚拟体主物体, g包围盒);

	return g单虚拟体主物体;
}




static S_Mesh* f_创建圆圈线(S_设备环境& ctx) {
	static S_Mesh* 圆圈线 = nullptr;
	if (圆圈线) {
		圆圈线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_Vulkan);

		圆圈线->m_网格类型 = E_绘制方式::e_画线段;
		圆圈线->m_线宽 = 1.0;

		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(20);
		f_graph_计算圆坐标XY({}, 0.2, 20, 圆顶点.data());
		顶点.reserve(20);
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		f_mesh_fill顶点数据(圆圈线, 顶点);
		f_mesh_计算包围盒(圆圈线);
	}
	
	return 圆圈线;
}



void f_node_设置物体光照材质(S_物体* ob) {
	switch (ob->m_Type) {
		case E_物体类型::t_多边形: {
			f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), E_物体网格元素类型::e_MT_焦点);
			f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), E_物体网格元素类型::e_MT_面);
			f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_边);
			f_ob_set材质(ob, f_NodeCtx_get逐顶点点材质(), E_物体网格元素类型::e_MT_点);
			f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_框);

			f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), E_物体网格元素类型::e_MT_光照);
			f_ob_set材质(ob, f_g_预设材质().g_PBR, E_物体网格元素类型::e_MT_纹理);
			f_ob_set材质(ob, f_NodeCtx_get物理光照轮廓材质(), E_物体网格元素类型::e_MT_轮廓边);
			f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_线);

			
			break;
		}
		case E_物体类型::t_粒子系统:
		case E_物体类型::t_网格物体: {
			f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), E_物体网格元素类型::e_MT_焦点);
			f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), E_物体网格元素类型::e_MT_面);
			f_ob_set材质(ob, f_NodeCtx_get基本光照线材质(), E_物体网格元素类型::e_MT_边);
			f_ob_set材质(ob, f_NodeCtx_get基本光照点材质(), E_物体网格元素类型::e_MT_点);
			f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_框);

			f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), E_物体网格元素类型::e_MT_光照);
			f_ob_set材质(ob, f_g_预设材质().g_PBR, E_物体网格元素类型::e_MT_纹理);
			f_ob_set材质(ob, f_NodeCtx_get物理光照轮廓材质(), E_物体网格元素类型::e_MT_轮廓边);
			f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_线);
			break;
		}
	}
}

void f_node_物体绘制属性设置(S_物体* ob) {
	f_ob_set颜色2(ob, {}, ob->m_实例ID);
	f_ob_set颜色2(ob, S_节点UI主题::uic_模型面, ob->m_实例ID, E_物体网格元素类型::e_MT_面);
	f_ob_set颜色2(ob, S_节点UI主题::uic_模型面, ob->m_实例ID, E_物体网格元素类型::e_MT_光照);
	f_ob_set颜色2(ob, S_节点UI主题::uic_模型线, ob->m_实例ID, E_物体网格元素类型::e_MT_边);
	f_ob_set颜色2(ob, S_节点UI主题::uic_模型点, ob->m_实例ID, E_物体网格元素类型::e_MT_点);

	if (ob->m_DataNum > 3) {
		f_ob_set颜色2(ob, S_节点UI主题::uic_模型线, ob->m_实例ID, E_物体网格元素类型::e_MT_框);
	}

	auto 网格属性 = f_init_MeshTranform();
	网格属性.m_Activate = 0;
	for (uint32 i = 0; i < ob->m_DataNum; ++i) {
		f_mesh_set绘制内存属性(f_ob_getMesh(ob, i), {});
		f_mesh_set网格元素绘制属性(f_ob_getMesh(ob, i), 网格属性);
	}

	网格属性.m_Activate = 1;
	f_mesh_set网格元素绘制属性(f_ob_getMesh(ob, 0), 网格属性);
}


void f_node_构建多边形网格对象(S_物体* ob, S_设备环境& ctx) {
	f_ob_set数据槽数量(ob, 9);

	auto* mesh_面 = f_surface_创建网格对象(nullptr, ctx, ctx.m_支持光追, E_网格数据枚举::e_Mesh_Vulkan);
	auto* mesh_点 = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	auto* mesh_边 = f_surface_创建实例(mesh_面, true, false, true, false, false, false);
	S_Mesh* 光照网格 = f_surface_创建实例(mesh_面, true, true, true, true, true, true);
	S_Mesh* 纹理网格 = f_surface_创建实例(mesh_面, true, true, true, true, true, true);
	S_Mesh* 轮廓网格 = f_surface_创建实例(mesh_面, true, true, true, true, true, false);
	S_Mesh* 线网格 = f_surface_创建实例(mesh_边, true, false, false, false, false, false);

	S_Mesh* mesh_包围盒 = f_surface_创建实例(f_buf_getGlobal().g_me_包围盒网格);

	f_ob_set数据(ob, f_surface_创建实例(mesh_面), E_物体网格元素类型::e_MT_焦点);
	f_ob_set数据(ob, mesh_面, E_物体网格元素类型::e_MT_面);
	f_ob_set数据(ob, mesh_边, E_物体网格元素类型::e_MT_边);
	f_ob_set数据(ob, mesh_包围盒, E_物体网格元素类型::e_MT_框);
	f_ob_set数据(ob, 光照网格, E_物体网格元素类型::e_MT_光照);
	f_ob_set数据(ob, 纹理网格, E_物体网格元素类型::e_MT_纹理);
	f_ob_set数据(ob, 轮廓网格, E_物体网格元素类型::e_MT_轮廓边);
	f_ob_set数据(ob, 线网格, E_物体网格元素类型::e_MT_线);
	f_ob_set数据(ob, mesh_点, E_物体网格元素类型::e_MT_点);
	
	f_me_alloc多维材质槽(轮廓网格, 1, f_NodeCtx_get物理光照轮廓材质());

	f_node_设置物体光照材质(ob);
	f_ob_set线宽(ob, 3.0, 0);

	f_node_物体绘制属性设置(ob);

	auto 网格属性 = f_init_MeshTranform();
	网格属性.m_Activate = 1;
	网格属性.m_Color = f_PackData4X8({ 0,0,0,255 });

	f_mesh_set网格元素绘制属性(f_ob_getMesh(ob), 网格属性);
	f_mesh_get网格元素绘制属性(mesh_包围盒).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

	//ob->m_Name = S_节点数据::g_物体名称分配器.f_Gen(u"几何体节点多边形物体");
}

void f_node_创建粒子物体数据(S_物体* ob, S_设备环境& ctx) {
	f_ob_set数据槽数量(ob, 9);

	auto* mesh_AABB = f_surface_创建网格对象(nullptr, ctx, ctx.m_支持光追, E_网格数据枚举::e_Mesh_Vulkan);
	f_mesh_切换顶点类型(mesh_AABB, E_顶点组合标志::e_包围盒, 0);

	auto* mesh_点 = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	auto* mesh_线 = f_surface_创建实例(mesh_点, true, false, true, false, false, false);
	S_Mesh* 光照网格 = f_surface_创建实例(mesh_AABB, true, true, true, true, true, true);
	S_Mesh* 纹理网格 = f_surface_创建实例(mesh_AABB, true, true, true, true, true, true);
	S_Mesh* 轮廓网格 = f_surface_创建实例(mesh_点, true, true, true, true, true, false);
	S_Mesh* 边网格 = f_surface_创建实例(mesh_点, true, false, false, false, false, false);

	S_Mesh* mesh_包围盒 = f_surface_创建实例(f_buf_getGlobal().g_me_包围盒网格);

	f_ob_set数据(ob, f_surface_创建实例(mesh_点), E_物体网格元素类型::e_MT_焦点);
	f_ob_set数据(ob, mesh_AABB, E_物体网格元素类型::e_MT_面);
	f_ob_set数据(ob, mesh_线, E_物体网格元素类型::e_MT_边);
	f_ob_set数据(ob, mesh_包围盒, E_物体网格元素类型::e_MT_框);
	f_ob_set数据(ob, 光照网格, E_物体网格元素类型::e_MT_光照);
	f_ob_set数据(ob, 纹理网格, E_物体网格元素类型::e_MT_纹理);
	f_ob_set数据(ob, 轮廓网格, E_物体网格元素类型::e_MT_轮廓边);
	f_ob_set数据(ob, 边网格, E_物体网格元素类型::e_MT_线);
	f_ob_set数据(ob, mesh_点, E_物体网格元素类型::e_MT_点);

	f_me_alloc多维材质槽(轮廓网格, 1, f_NodeCtx_get物理光照轮廓材质());
	f_me_alloc多维材质槽(mesh_AABB, 1, f_NodeCtx_getAABB材质());

	

	f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), E_物体网格元素类型::e_MT_焦点);
	f_ob_set材质(ob, f_NodeCtx_getAABB材质(), E_物体网格元素类型::e_MT_面);
	f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_边);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点点材质(), E_物体网格元素类型::e_MT_点);
	f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_框);

	f_ob_set材质(ob, f_NodeCtx_getAABB材质(), E_物体网格元素类型::e_MT_光照);
	f_ob_set材质(ob, f_NodeCtx_getAABB材质(), E_物体网格元素类型::e_MT_纹理);
	f_ob_set材质(ob, f_NodeCtx_get物理光照轮廓材质(), E_物体网格元素类型::e_MT_轮廓边);
	f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_线);

	f_ob_set线宽(ob, 3.0, 0);

	f_node_物体绘制属性设置(ob);

	auto 网格属性 = f_init_MeshTranform();
	网格属性.m_Activate = 1;
	网格属性.m_Color = f_PackData4X8({ 0,0,0,255 });

	f_mesh_set网格元素绘制属性(f_ob_getMesh(ob), 网格属性);
	f_mesh_get网格元素绘制属性(mesh_包围盒).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

}


S_物体* f_node_网格节点创建物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_网格物体);
	//f_node_创建网格物体数据(ctx, ob);
	//ob->m_Name = S_节点数据::g_物体名称分配器.f_Gen(u"网格节点创建物体");
	return ob;
}

void f_node_构建物体模型(S_物体* ob, S_设备环境& ctx) {
	switch (ob->m_Type) {
		case E_物体类型::t_多边形: f_node_构建多边形网格对象(ob, ctx); break;
		case E_物体类型::t_粒子系统:
		//case E_物体类型::t_网格物体: f_node_创建网格物体数据(ctx, ob); break;
		//case E_物体类型::t_粒子系统: f_node_创建粒子物体数据(ob, ctx); break;
		case E_物体类型::t_虚拟体: 
			
			ob->m_视口显示模式 = 0xff;
			ob->m_视口显示模式 |= ob->m_视口显示模式 << 16;

			break;
		default:
			break;
	}
}

void f_node_设置物体权重材质(S_物体* ob) {
	switch (ob->m_Type) {
		case E_物体类型::t_多边形: {
			f_ob_set材质(ob, f_NodeCtx_get权重可视面材质(), E_物体网格元素类型::e_MT_面);
			break;
		}
		case E_物体类型::t_网格物体: {
			f_ob_set材质(ob, f_NodeCtx_get权重可视面材质(), E_物体网格元素类型::e_MT_面);
			break;
		}
	}
}


S_物体* f_node_网格节点创建连续线物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_网格物体);
	ob->m_Name = u"连续线";
	f_ob_set数据槽数量(ob, 1);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点连续线材质(), 0);

	f_ob_set线宽(ob, 1.0, 0);

	return ob;
}

S_物体* f_node_网格节点创建线段物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_网格物体);
	ob->m_Name = u"线段";
	f_ob_set数据槽数量(ob, 1);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 0);

	f_ob_set线宽(ob, 1.0, 0);

	return ob;
}

S_物体* f_node_网格节点创建点物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_网格物体);
	ob->m_Name = u"点";
	f_ob_set数据槽数量(ob, 1);

	auto* mesh = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点点材质(), 0);

	f_ob_set线宽(ob, 1.0, 0);

	return ob;
}


void f_node_创建模型物体组(S_OBArray* 物体, uint32 num, E_物体类型 type, S_设备环境& ctx, E_物体类型 附加类型) {
	uint32 old_num = 物体->count;

	std::vector<S_物体*> 删除物体;
	for (uint32 i = num; i < old_num; ++i) {
		if (物体->ptr_userData[i]) {
			f_node_物体从主场景中移除(物体->ptr_userData[i]);
			f_node_从全局容器移除物体(物体->ptr_userData[i]);

			删除物体.push_back(物体->ptr_userData[i]);
		}
	}
	if(删除物体.size()) f_node_删除物体(删除物体);


	f_core_array_resize((S_Array*)物体, num);
	for (uint32 i = old_num; i < num; ++i) {
		
		switch (type) {
			case E_物体类型::t_网格物体:
				物体->ptr_userData[i] = f_node_网格节点创建物体数据(ctx);
				break;
			case E_物体类型::t_多边形:
				物体->ptr_userData[i] = f_ob_创建(ctx, E_物体类型::t_多边形);
				f_node_构建多边形网格对象(物体->ptr_userData[i], ctx);
				break;

			case E_物体类型::t_虚拟体: {
				物体->ptr_userData[i] = f_ob_创建(ctx, type);
				物体->ptr_userData[i]->m_视口显示模式 = 0xffff | 0xffff << 16;
				break;
			}
			case E_物体类型::t_实例: {
				break;
			}
			default:
				break;
		}

		f_ob_set附属类型(物体->ptr_userData[i], 附加类型);
		switch (附加类型) {
			case E_物体类型::t_物理力: {
				物体->ptr_userData[i]->m_UserData = malloc(sizeof(S_PBF_force));
				break;
			}
			default:
				break;
		}

		f_node_物体添加到全局容器(物体->ptr_userData[i]);
		f_node_物体添加到主场景(物体->ptr_userData[i]);
	}
}


void f_node_销毁模型网格(S_物体* ob) {
	switch (ob->m_Type) {
		case E_物体类型::t_网格物体:
			f_surface_销毁网格(f_ob_getMesh(ob, 0));
			f_surface_销毁网格(f_ob_getMesh(ob, 1));
			f_surface_销毁网格(f_ob_getMesh(ob, 2));
			f_surface_销毁网格(f_ob_getMesh(ob, 4));
			break;
		case E_物体类型::t_多边形:
			f_surface_销毁网格(f_ob_getMesh(ob, 0));
			f_surface_销毁网格(f_ob_getMesh(ob, 1));
			f_surface_销毁网格(f_ob_getMesh(ob, 2));
			f_surface_销毁网格(f_ob_getMesh(ob, 3));
			break;
		default:
			break;
	}

	f_ob_set数据槽数量(ob, 0);
}


void f_node_创建纹理组(S_TexArray* 纹理, uint32 num, S_设备环境& ctx) {
	uint32 old_num = 纹理->count;
	
	for (uint32 i = num; i < old_num; ++i) {
		f_scene_销毁纹理(f_NodeCtx_get默认场景(), 纹理->ptr_userData[i], E_纹理分组类型::e_2D纹理);
	}

	f_core_array_resize((S_Array*)纹理, num);
	for (uint32 i = old_num; i < num; ++i) {
		纹理->ptr_userData[i] = f_scene_创建纹理(f_NodeCtx_get默认场景(), ctx, u"纹理集", E_纹理分组类型::e_2D纹理);
	}
}

void f_node_销毁纹理组(S_TexArray* 纹理) {
	for (uint32 i = 0; i < 纹理->count; ++i) {
		f_scene_销毁纹理(f_NodeCtx_get默认场景(), 纹理->ptr_userData[i], E_纹理分组类型::e_2D纹理);
	}
}


S_物体* f_node_构建曲线物体数据(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_空间曲线);
	ob->m_Name = u"曲线物体";
	ob->m_视口显示模式 = 7 | (7<<16);
	f_ob_set数据槽数量(ob, 5);

	
	S_Mesh* 曲线 = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	S_Mesh* 控制点 = f_surface_创建实例(曲线, true, false, false, false, false, false);
	S_Mesh* 控制线 = f_surface_创建实例(曲线, true, false, false, false, false, false);
	S_Mesh* 法向 = f_surface_创建实例(曲线, true, true, true, true, true, true);

	S_Mesh* mesh_包围盒 = f_surface_创建实例(f_buf_getGlobal().g_me_包围盒网格);
	f_mesh_get网格元素绘制属性(mesh_包围盒).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;
	
	控制点->m_显示 = false;
	控制线->m_显示 = false;
	法向->m_显示 = false;
	//f_ob_set数据(ob, 焦点, 0);
	f_ob_set数据(ob, 曲线, 0);
	f_ob_set数据(ob, 控制点, 1);
	f_ob_set数据(ob, 控制线, 2);
	f_ob_set数据(ob, 法向, 3);
	f_ob_set数据(ob, mesh_包围盒, 4);

	//f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), E_物体网格元素类型::e_MT_焦点);

	f_me_alloc多维材质槽(曲线, 1, f_NodeCtx_get逐顶点曲线材质());
	f_me_alloc多维材质槽(控制点, 1, f_NodeCtx_get逐顶点曲线控制点材质());
	f_me_alloc多维材质槽(控制线, 1, f_NodeCtx_get逐顶点曲线控制线材质());
	f_me_alloc多维材质槽(法向, 1, f_NodeCtx_get逐顶点曲线材质());
	f_me_alloc多维材质槽(mesh_包围盒, 1, f_NodeCtx_get基本光照线段材质());


	f_ob_set颜色2(ob, { 10,10,10,255 }, ob->m_实例ID, 0);
	f_ob_set颜色2(ob, { 100,100,10,255 }, ob->m_实例ID, 1);
	f_ob_set颜色2(ob, { 100,100,100,255 }, ob->m_实例ID, 2);
	f_ob_set颜色2(ob, { 0,0,0,255 }, ob->m_实例ID, 3);
	f_ob_set颜色2(ob, { 0,0,0,255 }, ob->m_实例ID, 4);

	f_ob_set线宽(ob, 1.0, 0);
	f_ob_set线宽(ob, 1.0, 1);
	f_ob_set线宽(ob, 2.0, 2);
	f_ob_set线宽(ob, 2.0, 3);
	f_ob_set线宽(ob, 1.0, 4);


	
	//f_mesh_set绘制内存属性(焦点, {});
	f_mesh_set绘制内存属性(曲线, {});
	f_mesh_set绘制内存属性(控制点, {});
	f_mesh_set绘制内存属性(控制线, {});
	f_mesh_set绘制内存属性(mesh_包围盒, {});
	return ob;
}



void f_node_物体节点创建物体数据_单色明暗(S_物体* ob) {
	f_ob_set数据槽数量(ob, 3);

	S_Mesh* mesh = (S_Mesh*)(ob->m_Data[0]);
	S_Mesh* m1 = f_surface_创建实例(mesh);
	S_Mesh* m2 = f_surface_创建实例(mesh);
	f_ob_set数据(ob, m1, 1);
	f_ob_set数据(ob, m2, 2);

	f_ob_set材质(ob, f_NodeCtx_get单色描边材质(), 0);
	f_ob_set材质(ob, f_NodeCtx_get单色平直面材质(), 1);
	f_ob_set材质(ob, f_NodeCtx_get单色线材质(), 2);
}

void f_node_将现有物体包装成骨骼网格(S_设备环境& ctx, S_物体* 骨骼, S_物体* 骨节) {
	S_单色材质包 包 = f_node_get骨骼可视材质(ctx);


	f_ob_set数据槽数量(骨骼, 2);
	S_Mesh* mesh = f_ob_getMesh(骨骼, 0);
	S_Mesh* m1 = f_surface_创建实例(mesh, true);
	f_ob_set数据(骨骼, m1, 1);

	f_ob_set材质(骨骼, 包.m_描边, 0);
	f_ob_set材质(骨骼, 包.m_面, 1);

	mesh->m_深度控制 = { 0.00001f, 0.01f };
	m1->m_深度控制 = { 0.001f, 0.001f };

	if (骨节) {
		f_ob_set数据槽数量(骨节, 2);
		mesh = f_ob_getMesh(骨节, 0);
		S_Mesh* m2 = f_surface_创建实例(mesh);
		f_ob_set数据(骨节, m2, 1);

		f_ob_set材质(骨节, 包.m_描边, 0);
		f_ob_set材质(骨节, 包.m_面, 1);

		mesh->m_深度控制 = { 0.00001f, 0.01f };
		m2->m_深度控制 = { 0.001f, 0.001f };
	}
}

//S_物体* f_node_线网格节点创建物体数据(S_设备环境& ctx) {
//	S_物体* obj = f_ob_创建物体(ctx, E_物体类型::t_网格物体);
//
//	f_ob_set数据槽数量(obj, 3);
//	auto* mesh = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
//	f_ob_set数据(obj, mesh);
//
//	S_Mesh* m1 = f_surface_创建实例(mesh);
//	f_ob_set数据(obj, m1, 1);
//	f_ob_set数据(obj, m1, 2);
//
//	//描边材质网格必须要最前面
//	f_ob_set材质(obj, f_NodeCtx_get线段描边材质(), 0);
//	f_ob_set材质(obj, f_NodeCtx_get逐顶点线段材质(), 1);
//	f_ob_set材质(obj, f_NodeCtx_get逐顶点线段材质(), 2);
//
//	f_ob_set线宽(obj, 1.2, 0);
//
//	obj->m_Name = L"几何体节点创建物体";
//	return obj;
//}

S_物体* f_node_创建虚拟体(S_设备环境& ctx, E_虚拟体类型 类型) {
	
	static S_Mesh* mesh = nullptr;
	static uint32 交叉轴顶点数量 = 0;
	static uint32 方向轴顶点数量 = 0;
	static uint32 线框球顶点数量 = 0;

	static uint32 交叉轴顶点索引数量 = 0;
	static uint32 方向轴顶点索引数量 = 0;
	static uint32 线框球顶点索引数量 = 0;

	if (!mesh) {
		mesh = f_surface_创建网格对象(ctx, E_网格数据枚举::e_Mesh_Vulkan);

		DEF_3Fs v;
		DEF_3Fs n;
		DEF_2Fs uv;
		DEF_Is index;
		std::vector<S_VkDrawIndirectCommand> Indirect;

		f_graph_构建交叉轴(v, n, uv, index);
		f_surface_push顶点(mesh, v);
		f_surface_push索引(mesh, index);
		交叉轴顶点数量 = v.size();
		交叉轴顶点索引数量 = index.size();
		S_虚拟体ID偏移::Indirect_交叉轴.firstInstance = 0;
		S_虚拟体ID偏移::Indirect_交叉轴.instanceCount = 1;
		S_虚拟体ID偏移::Indirect_交叉轴.vertexOffset = 0;
		S_虚拟体ID偏移::Indirect_交叉轴.indexCount = 交叉轴顶点索引数量;
		S_虚拟体ID偏移::Indirect_交叉轴.firstIndex = 0;


		f_graph_构建方向轴(v, n, uv, index);
		f_surface_push顶点(mesh, v);
		f_surface_push索引(mesh, index);
		方向轴顶点数量 = v.size();
		方向轴顶点索引数量 = index.size();
		S_虚拟体ID偏移::Indirect_方向轴.firstInstance = 0;
		S_虚拟体ID偏移::Indirect_方向轴.instanceCount = 1;
		S_虚拟体ID偏移::Indirect_方向轴.vertexOffset = 交叉轴顶点数量;
		S_虚拟体ID偏移::Indirect_方向轴.indexCount = 方向轴顶点索引数量;
		S_虚拟体ID偏移::Indirect_方向轴.firstIndex = 交叉轴顶点索引数量;


		f_graph_构建线框球(v, n, uv, index, 32);
		f_surface_push顶点(mesh, v);
		f_surface_push索引(mesh, index);
		
		线框球顶点数量 = v.size();
		线框球顶点索引数量 = index.size();
		S_虚拟体ID偏移::Indirect_线框球.firstInstance = 0;
		S_虚拟体ID偏移::Indirect_线框球.instanceCount = 1;
		S_虚拟体ID偏移::Indirect_线框球.vertexOffset = 交叉轴顶点数量 + 方向轴顶点数量;
		S_虚拟体ID偏移::Indirect_线框球.indexCount = 线框球顶点索引数量;
		S_虚拟体ID偏移::Indirect_线框球.firstIndex = 交叉轴顶点索引数量 + 方向轴顶点索引数量;

		mesh->m_线宽 = 4.0;
	}



	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_虚拟体);
	f_ob_set数据槽数量(ob, 1);
	f_ob_set数据(ob, mesh);
	f_ob_set材质(ob, f_NodeCtx_get单色线段材质());

	return ob;
}

S_物体* f_node_创建虚线(S_设备环境& ctx) {
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_线段);
	f_ob_set数据槽数量(ob, 1);
	ob->m_颜色 = {200,200,200,255};

	auto 网格属性 = f_init_MeshTranform();

	S_Mesh* me = f_surface_创建网格对象(ctx, E_网格数据枚举::e_Mesh_Vulkan);
	me->m_线宽 = 0.8;
	f_mesh_set绘制内存属性(me, {});
	f_mesh_set网格元素绘制属性(me, 网格属性);

	f_ob_set数据(ob, me);
	f_ob_set材质(ob, f_NodeCtx_get基本光照线段材质());
	f_ob_set颜色2(ob, ob->m_颜色, 0);
	

	std::vector<S_VNT1> 顶点 = { {0,0,0}, {}, {} };
	std::vector<uint32> 索引 = { 0 };
	f_mesh_fill顶点数据(me, 顶点);
	f_me_fill索引(me, 索引);
	f_mesh_计算包围盒(me);

	return ob;
}


S_物体* f_node_创建包围盒虚拟体(S_设备环境& ctx) {
	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_TransformMode = 0;
	S_材质管线* material = f_NodeCtx_get单虚拟体材质(ctx);

	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_网格物体);
	
	f_ob_set数据槽数量(ob, 1);
	f_ob_set数据(ob, g包围盒);
	f_ob_set材质(ob, material);

	return ob;
}




static S_物体* g虚拟体主物体 = nullptr;
static S_Mesh* 边界线 = nullptr;
static S_Mesh* 中心圆 = nullptr;
static S_Mesh* 方向线 = nullptr;
static S_Mesh* 发光面 = nullptr;

static uint32 g区域光InstanceID = 0;
static S_VkDrawIndirectCommand 中心Indirect = {};
static S_VkDrawIndirectCommand 中心_摄像机锥形Indirect = {};
static S_VkDrawIndirectCommand 中心_立方体Indirect = {};

static S_VkDrawIndirectCommand XY圆形Indirect = {};
static S_VkDrawIndirectCommand YZ圆形Indirect = {};
static S_VkDrawIndirectCommand XYZ圆形Indirect = {};
static S_VkDrawIndirectCommand 方向Indirect = {};
static S_VkDrawIndirectCommand 锥形Indirect = {};
static S_VkDrawIndirectCommand 边界线_并排线Indirect = {};
static S_VkDrawIndirectCommand 边界线_XY四边形Indirect = {};
static S_VkDrawIndirectCommand 边界线_链接线Indirect = {};

static S_VkDrawIndirectCommand 四边Indirect = {};
static S_VkDrawIndirectCommand XZ圆形Indirect = {};
static S_VkDrawIndirectCommand XZ缩放圆形Indirect = {};

static S_VkDrawIndirectCommand 方向线_Z_Indirect = {};
static S_VkDrawIndirectCommand 方向线_Y三角箭头_Indirect = {};
static S_VkDrawIndirectCommand 方向线_链接线_Indirect = {};

S_物体* f_node_创建虚拟体网格物体(S_设备环境& ctx, E_物体类型 类型) {
	
	const float 中心园半径 = 0.2;
	if (!中心圆) {
		中心圆 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);

		中心圆->m_网格类型 = E_绘制方式::e_画线段;
		中心圆->m_线宽 = 1.0;


		uint32 offset = 0;
		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(20);
		f_graph_计算圆坐标XY({}, 中心园半径, 20, 圆顶点.data());
		顶点.reserve(20);
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		
		中心Indirect = { 20, 1, 0, 0 };
		offset += 20;


		{
			//float32 r = tan(M_角度转弧度(1) * 0.5);
			float32 r = 0.5;
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });


			顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			中心_摄像机锥形Indirect = { 16, 1, offset, 0 };
			offset += 中心_摄像机锥形Indirect.vertexCount;
		}
		
		{
			中心_立方体Indirect = { 24, 1, offset, 0 };
			中心_立方体Indirect.vertexCount = f_graph_立方体线段(顶点, {1,1,1}, {}, S_RGBA8UI{0,0,0,255});
			中心_立方体Indirect.firstVertex = offset;
			offset += 中心_立方体Indirect.vertexCount;
		}


		offset = f_mesh_fill顶点数据(中心圆, 顶点);
		f_mesh_计算包围盒(中心圆);

		中心Indirect.firstVertex += offset;
		中心_摄像机锥形Indirect.firstVertex += offset;
		中心_立方体Indirect.firstVertex += offset;
	}


	
	if (!边界线) {
		
		边界线 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
		边界线->m_网格类型 = E_绘制方式::e_画连续线;
		边界线->m_线宽 = 1.0;


		uint32 offset = 0;
		std::vector<S_VC> 顶点;
		顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		四边Indirect = { 8, 1, offset, 0 };
		offset += 8;




		uint32 圆细分数量 = 128;
		std::vector<vec2> 圆顶点(圆细分数量);
		f_graph_计算圆坐标XY({}, 1.0, 圆细分数量, 圆顶点.data());
		XYZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		XY圆形Indirect = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		for (auto& e : 圆顶点) {
			顶点.push_back({ {0, e.y, e.x}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		YZ圆形Indirect = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;
		
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		XZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

		XYZ圆形Indirect.vertexCount = 圆细分数量 * 3;
		offset += 圆细分数量;



		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, -2, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		XZ缩放圆形Indirect = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		vec3 平行光线条1 = { 中心园半径 * sin(M_PI * 0.5 * 0.2), -中心园半径 * cos(M_PI * 0.5 * 0.2), 0 };
		vec3 平行光线条2 = { 中心园半径 * sin(M_PI * 0.5 * 0.5), -中心园半径 * cos(M_PI * 0.5 * 0.5), 0 };
		vec3 平行光线条3 = { 中心园半径 * sin(M_PI * 0.5), -中心园半径 * cos(M_PI * 0.5), 0 };
		
		顶点.push_back({ 平行光线条1, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ 平行光线条2, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ 平行光线条3, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		
		顶点.push_back({ {-平行光线条1.x, 平行光线条1.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条2.x, 平行光线条2.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条3.x, 平行光线条3.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		顶点.push_back({ {-平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
		边界线_并排线Indirect = { 12, 1, offset , 0 };
		offset += 12;



		顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		边界线_XY四边形Indirect = { 8, 1, offset , 0 };
		offset += 8;


		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		边界线_链接线Indirect = { 2, 1, offset , 0 };
		offset += 2;


		offset = f_mesh_fill顶点数据(边界线, 顶点);
		f_mesh_计算包围盒(边界线);
		
		四边Indirect.firstVertex += offset;
		XY圆形Indirect.firstVertex += offset;
		YZ圆形Indirect.firstVertex += offset;
		XZ圆形Indirect.firstVertex += offset;
		XYZ圆形Indirect.firstVertex += offset;
		XZ缩放圆形Indirect.firstVertex += offset;
		边界线_并排线Indirect.firstVertex += offset;
		边界线_XY四边形Indirect.firstVertex += offset;
	}

	if (!方向线) {
		方向线 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
		方向线->m_网格类型 = E_绘制方式::e_画线段;
		方向线->m_线宽 = 1.0;

		uint32 offset = 0;

		std::vector<S_VC> 顶点;
		顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向Indirect = { 2, 1, 0, 0 };
		offset += 2;

		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		锥形Indirect = { 4, 1, offset, 0 };
		offset += 4;

		顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,0,1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向线_Z_Indirect = { 2, 1, offset, 0 };
		offset += 2;

		顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向线_Y三角箭头_Indirect = { 6, 1, offset, 0 };
		offset += 6;


		顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {1, 1, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		方向线_链接线_Indirect = { 2, 1, offset , 0 };
		offset += 2;
		

		offset = f_mesh_fill顶点数据(方向线, 顶点);
		f_mesh_计算包围盒(方向线);

		方向Indirect.firstVertex += offset;
		锥形Indirect.firstVertex += offset;
		方向线_Z_Indirect.firstVertex += offset;
		方向线_Y三角箭头_Indirect.firstVertex += offset;
		方向线_链接线_Indirect.firstVertex += offset;
	}

	
	
	

	if (!g虚拟体主物体) {
		g虚拟体主物体 = f_ob_创建(ctx, E_物体类型::t_包);
		
		f_ob_set数据槽数量(g虚拟体主物体, 3);

		f_ob_set数据(g虚拟体主物体, 中心圆, 0);
		f_ob_set数据(g虚拟体主物体, 边界线, 1);
		f_ob_set数据(g虚拟体主物体, 方向线, 2);

		f_ob_set材质(g虚拟体主物体, f_NodeCtx_get灯光模型中心圆材质(中心圆->m_Ctx), 0);
		f_ob_set材质(g虚拟体主物体, f_NodeCtx_get灯光模型范围线材质(边界线->m_Ctx), 1);
		f_ob_set材质(g虚拟体主物体, f_NodeCtx_get灯光模型方向线材质(方向线->m_Ctx), 2);
		

		f_mesh_gen网格元素绘制属性(中心圆, 1);
		f_mesh_gen网格元素绘制属性(边界线, 1);
		f_mesh_gen网格元素绘制属性(方向线, 1);

		f_node_物体绘制属性设置(g虚拟体主物体);
		
		f_scene_添加物体(f_NodeCtx_get默认场景(), g虚拟体主物体);
		S_节点数据::m_全局物体set.insert(g虚拟体主物体);
		g虚拟体主物体->m_根实例 = true;
	}

	
	//return nullptr;
	S_物体* m_Ob = f_ob_创建(ctx, 类型);
	f_ob_add子物体(g虚拟体主物体, m_Ob);

	if (g虚拟体主物体->m_变换矩阵.m_Mem.m_数量 < g虚拟体主物体->m_子物体.size()) {
		f_ob_添加矩阵(g虚拟体主物体);
	}

	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	
	switch (类型) {
	case E_物体类型::t_平行光: {
		m_Ob->m_ID = f_scene_渲染器分配平行光内存(f_NodeCtx_get默认场景());
		f_node_创建平行光虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_点光源: {
		//m_Ob->m_ID = f_scene_渲染器分配点光源内存(f_NodeCtx_get默认场景());
		f_node_创建点光源虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_区域光 : {
		m_Ob->m_ID = f_scene_渲染器分配区域光内存(f_NodeCtx_get默认场景());
		f_node_创建区域光虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_聚光灯: {
		m_Ob->m_ID = f_scene_渲染器分配聚光灯内存(f_NodeCtx_get默认场景());
		f_node_创建聚光灯虚拟体(m_Ob);
		break;
	}
	case E_物体类型::t_虚拟体: {
		f_node_创建摄像机虚拟体(m_Ob);
		break;
	}
	}

	return m_Ob;
}

void f_node_释放虚拟体网格() {
	if(g虚拟体主物体) f_ob_clear子物体(g虚拟体主物体);
}


S_物体* f_node_get多元素虚拟体根物体(S_设备环境& ctx) {
	static S_物体* g虚拟体根物体 = nullptr;
	if (!g虚拟体根物体) {
		
		const float 中心园半径 = 0.2;
		if (!g虚拟体中心圆) {
			g虚拟体中心圆 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);

			g虚拟体中心圆->m_网格类型 = E_绘制方式::e_画线段;
			g虚拟体中心圆->m_线宽 = 1.0;


			uint32 offset = 0;
			std::vector<S_VC> 顶点;
			std::vector<vec2> 圆顶点(20);
			f_graph_计算圆坐标XY({}, 中心园半径, 20, 圆顶点.data());
			顶点.reserve(20);
			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}

			g虚拟体中心Indirect = { 20, 1, 0, 0 };
			offset += 20;



			{
				//float32 r = tan(M_角度转弧度(1) * 0.5);
				float32 r = 0.5;
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });


				顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				顶点.push_back({ {0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				顶点.push_back({ {0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				顶点.push_back({ {-0.5f, -0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
				顶点.push_back({ {-0.5f, 0.5f, r}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

				g虚拟体中心_摄像机锥形Indirect = { 16, 1, offset, 0 };
				offset += g虚拟体中心_摄像机锥形Indirect.vertexCount;
			}

			{
				g虚拟体中心_立方体Indirect = { 24, 1, offset, 0 };
				g虚拟体中心_立方体Indirect.vertexCount = f_graph_立方体线段(顶点, {1,1,1}, {}, S_RGBA8UI{0,0,0,255});
				g虚拟体中心_立方体Indirect.firstVertex = offset;
				offset += g虚拟体中心_立方体Indirect.vertexCount;
			}


			offset = f_mesh_fill顶点数据(g虚拟体中心圆, 顶点);
			f_mesh_计算包围盒(g虚拟体中心圆);

			g虚拟体中心Indirect.firstVertex += offset;
			g虚拟体中心_摄像机锥形Indirect.firstVertex += offset;
			g虚拟体中心_立方体Indirect.firstVertex += offset;
		}



		if (!g虚拟体边界线) {

			g虚拟体边界线 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
			g虚拟体边界线->m_网格类型 = E_绘制方式::e_画连续线;
			g虚拟体边界线->m_线宽 = 1.0;


			uint32 offset = 0;
			std::vector<S_VC> 顶点;
			顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

			顶点.push_back({ {-1, 0, 1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, 0, -1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体四边Indirect = { 8, 1, offset, 0 };
			offset += 8;





			uint32 圆细分数量 = 128;
			std::vector<vec2> 圆顶点(圆细分数量);
			f_graph_计算圆坐标XY({}, 1.0, 圆细分数量, 圆顶点.data());
			g虚拟体XYZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体XY圆形Indirect = { 圆细分数量, 1, offset, 0 };
			offset += 圆细分数量;

			for (auto& e : 圆顶点) {
				顶点.push_back({ {0, e.y, e.x}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体YZ圆形Indirect = { 圆细分数量, 1, offset, 0 };
			offset += 圆细分数量;

			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体XZ圆形Indirect = { 圆细分数量, 1, offset, 0 };

			g虚拟体XYZ圆形Indirect.vertexCount = 圆细分数量 * 3;
			offset += 圆细分数量;



			for (auto& e : 圆顶点) {
				顶点.push_back({ {e.x, -2, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			}
			g虚拟体XZ缩放圆形Indirect = { 圆细分数量, 1, offset, 0 };
			offset += 圆细分数量;

			vec3 平行光线条1 = { 中心园半径 * sin(M_PI * 0.5 * 0.2), -中心园半径 * cos(M_PI * 0.5 * 0.2), 0 };
			vec3 平行光线条2 = { 中心园半径 * sin(M_PI * 0.5 * 0.5), -中心园半径 * cos(M_PI * 0.5 * 0.5), 0 };
			vec3 平行光线条3 = { 中心园半径 * sin(M_PI * 0.5), -中心园半径 * cos(M_PI * 0.5), 0 };

			顶点.push_back({ 平行光线条1, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ 平行光线条2, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ 平行光线条3, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });

			顶点.push_back({ {-平行光线条1.x, 平行光线条1.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条1.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条2.x, 平行光线条2.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条2.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条3.x, 平行光线条3.y, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			顶点.push_back({ {-平行光线条3.x, -1, 0}, f_PackData4X8(S_RGBA8UI{200,200,0,255}) });
			g虚拟体边界线_并排线Indirect = { 12, 1, offset , 0 };
			offset += 12;



			顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, -1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, 1, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体边界线_XY四边形Indirect = { 8, 1, offset , 0 };
			offset += 8;



			offset = f_mesh_fill顶点数据(g虚拟体边界线, 顶点);
			f_mesh_计算包围盒(g虚拟体边界线);

			g虚拟体四边Indirect.firstVertex += offset;
			g虚拟体XY圆形Indirect.firstVertex += offset;
			g虚拟体YZ圆形Indirect.firstVertex += offset;
			g虚拟体XZ圆形Indirect.firstVertex += offset;
			g虚拟体XYZ圆形Indirect.firstVertex += offset;
			g虚拟体XZ缩放圆形Indirect.firstVertex += offset;
			g虚拟体边界线_并排线Indirect.firstVertex += offset;
			g虚拟体边界线_XY四边形Indirect.firstVertex += offset;
		}

		if (!g虚拟体方向线) {
			g虚拟体方向线 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
			g虚拟体方向线->m_网格类型 = E_绘制方式::e_画线段;
			g虚拟体方向线->m_线宽 = 1.0;

			uint32 offset = 0;

			std::vector<S_VC> 顶点;
			顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体方向Indirect = { 2, 1, 0, 0 };
			offset += 2;

			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0, 0, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-1, -2, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体锥形Indirect = { 4, 1, offset, 0 };
			offset += 4;

			顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,0,1}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体方向线_Z_Indirect = { 2, 1, offset, 0 };
			offset += 2;

			顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {-0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0,0.3,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			顶点.push_back({ {0.3,0,0.5f}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
			g虚拟体方向线_Y三角箭头_Indirect = { 6, 1, offset, 0 };
			offset += 6;


			offset = f_mesh_fill顶点数据(g虚拟体方向线, 顶点);
			f_mesh_计算包围盒(g虚拟体方向线);

			g虚拟体方向Indirect.firstVertex += offset;
			g虚拟体锥形Indirect.firstVertex += offset;
			g虚拟体方向线_Z_Indirect.firstVertex += offset;
			g虚拟体方向线_Y三角箭头_Indirect.firstVertex += offset;
		}




		{
			g虚拟体根物体 = f_ob_创建(ctx, E_物体类型::t_包);
			f_ob_创建矩阵(g虚拟体根物体);

			f_ob_set数据槽数量(g虚拟体根物体, 3);

			f_ob_set数据(g虚拟体根物体, g虚拟体中心圆, 0);
			f_ob_set数据(g虚拟体根物体, g虚拟体边界线, 1);
			f_ob_set数据(g虚拟体根物体, g虚拟体方向线, 2);

			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get虚拟体中心圆材质(g虚拟体中心圆->m_Ctx), 0);
			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get虚拟体范围线材质(g虚拟体边界线->m_Ctx), 1);
			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get虚拟体方向线材质(g虚拟体方向线->m_Ctx), 2);


			
			f_surface_add间接绘制(g虚拟体中心圆, S_VkDrawIndirectCommand{});
			f_surface_add间接绘制(g虚拟体边界线, S_VkDrawIndirectCommand{});
			f_surface_add间接绘制(g虚拟体方向线, S_VkDrawIndirectCommand{});

			f_node_物体添加到主场景(g虚拟体根物体);
		}
		
	}
	return g虚拟体根物体;
}

S_物体* f_node_get单元素虚拟体根物体(S_设备环境* ctx) {
	static S_物体* g虚拟体根物体 = nullptr;
	if (!g虚拟体根物体 && ctx) {

		uint32 offset = 0;
		uint32 圆细分数量 = 128;
		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(圆细分数量);
		
		f_graph_计算圆坐标XY({}, 0.5, 圆细分数量, 圆顶点.data());
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		gIndirect单元素虚拟体_XY圆 = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		gIndirect单元素虚拟体_XZ圆 = { 圆细分数量, 1, offset, 0 };
		offset += 圆细分数量;

		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0.5, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, -0.5, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		}
		顶点.push_back({ {-0.5f, -0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5f, 0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5f, -0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5f, 0.5, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });

		顶点.push_back({ {0, -0.5, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, 0.5, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, -0.5, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0, 0.5, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		gIndirect单元素虚拟体_圆柱 = { 圆细分数量*2+8, 1, offset, 0 };
		offset += gIndirect单元素虚拟体_圆柱.vertexCount;



		顶点.push_back({ {-0.5, 0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5,  0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5, 0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5,  0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5, 0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {-0.5, 0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5, 0, -0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0.5,  0, 0.5}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		gIndirect单元素虚拟体_平面 = { 8, 1, offset, 0 };
		offset += gIndirect单元素虚拟体_平面.vertexCount;


		g单元素虚拟体网格 = f_surface_创建网格对象(0, *ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
		g单元素虚拟体网格->m_网格类型 = E_绘制方式::e_画线段;
		offset = f_mesh_fill顶点数据(g单元素虚拟体网格, 顶点);
		
		gIndirect单元素虚拟体_XY圆.firstVertex += offset;
		gIndirect单元素虚拟体_XZ圆.firstVertex += offset;
		gIndirect单元素虚拟体_圆柱.firstVertex += offset;
		gIndirect单元素虚拟体_平面.firstVertex += offset;



		{
			g虚拟体根物体 = f_ob_创建(*ctx, E_物体类型::t_包);
			
			S_Vert_MeshDrawProp Prop{};
			Prop.MeshPropOffset = g单元素虚拟体网格->m_网格元素变换属性.m_Mem.m_偏移;
			f_mesh_set绘制内存属性(g单元素虚拟体网格, Prop);
			

			f_ob_set数据槽数量(g虚拟体根物体, 1);
			f_ob_set数据(g虚拟体根物体, g单元素虚拟体网格, 0);
			f_ob_set材质(g虚拟体根物体, f_NodeCtx_get单元素虚拟体材质(*ctx), 0);
			
			f_node_物体添加到主场景(g虚拟体根物体);
		}
	}
	return g虚拟体根物体;
}



void f_node_创建平行光虚拟体(S_物体* ob) {

	auto indirect = 中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = 边界线_并排线Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);



	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);




	S_Vert_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(中心圆, 中心圆Prop);
	S_Vert_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(边界线, 边界线Prop);
	S_Vert_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(方向线, 方向线Prop);
}

void f_node_创建点光源虚拟体(S_物体* ob) {
	
	auto indirect = 中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = XYZ圆形Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);



	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NONE;
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NONE;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);


	S_Vert_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(中心圆, 中心圆Prop);
	S_Vert_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(边界线, 边界线Prop);
	S_Vert_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(方向线, 方向线Prop);
}

void f_node_创建聚光灯虚拟体(S_物体* ob) {
	
	auto indirect中心 = 中心Indirect;
	auto indirect边界 = XZ缩放圆形Indirect;
	auto indirect方向 = 锥形Indirect;
	f_node_设置聚光灯虚拟体绘制(indirect中心, indirect边界, indirect方向, ob->m_实例ID);
	f_surface_add间接绘制(中心圆, indirect中心);
	f_surface_add间接绘制(边界线, indirect边界);
	f_surface_add间接绘制(方向线, indirect方向);



	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NONE;
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);



	S_Vert_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(中心圆, 中心圆Prop);
	S_Vert_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(边界线, 边界线Prop);
	S_Vert_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(方向线, 方向线Prop);

}

void f_node_创建区域光虚拟体(S_物体* ob) {

	auto indirect = 中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = 四边Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);

	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);


	S_Vert_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(中心圆, 中心圆Prop);
	S_Vert_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(边界线, 边界线Prop);
	S_Vert_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(方向线, 方向线Prop);
}


S_物体* f_node_创建摄像机虚拟体(S_物体* ob) {
	//return ob;
	auto indirect中心 = 中心_摄像机锥形Indirect;
	auto indirect边界 = 边界线_XY四边形Indirect;
	auto indirect方向 = 方向线_Y三角箭头_Indirect;
	
	f_node_设置摄像机虚拟体绘制(indirect中心, indirect边界, indirect方向, 0);
	f_surface_add间接绘制(中心圆, indirect中心);
	f_surface_add间接绘制(边界线, indirect边界);
	f_surface_add间接绘制(方向线, indirect方向);
	ob->m_PickIndirect = indirect中心;


	S_Vert_MeshDrawProp 中心圆Prop{};
	中心圆Prop.MeshPropOffset = 中心圆->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(中心圆, 中心圆Prop);
	S_Vert_MeshDrawProp 边界线Prop{};
	边界线Prop.MeshPropOffset = 边界线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(边界线, 边界线Prop);
	S_Vert_MeshDrawProp 方向线Prop{};
	方向线Prop.MeshPropOffset = 方向线->m_网格元素变换属性.m_Mem.m_偏移;
	f_mesh_set绘制内存属性(方向线, 方向线Prop);

	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;

	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);
	return ob;
}

void f_node_设置摄像机虚拟网格(S_物体* ob, S_摄像机* 摄像机) {
	S_MeshTranformProp 线属性 = f_buf_网格元素变换属性_at(中心圆->m_网格元素变换属性, ob->m_实例ID);

	线属性.m_DottedLine = 1;
	线属性.m_Remote = 1;
	线属性.m_Scale = 1;
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;
	线属性.m_TransformMode = 0;
	
	vec3 s = f_camera_计算摄像机以角度缩放大小(摄像机);
	线属性.m_YScale = s.y;
	线属性.m_ZScale = s.z;
	
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

	f_buf_网格元素变换属性_at(边界线->m_网格元素变换属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_buf_网格元素变换属性_at(边界线->m_网格元素变换属性, ob->m_实例ID).m_YScale = s.y;
	f_buf_网格元素变换属性_at(边界线->m_网格元素变换属性, ob->m_实例ID).m_ZScale = s.z;

	f_buf_网格元素变换属性_at(中心圆->m_网格元素变换属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;
	f_buf_网格元素变换属性_at(中心圆->m_网格元素变换属性, ob->m_实例ID).m_YScale = s.y;
	f_buf_网格元素变换属性_at(中心圆->m_网格元素变换属性, ob->m_实例ID).m_ZScale = s.z;

	f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;
	f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID).m_YScale = s.y;
	f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID).m_ZScale = s.z;
	f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID).m_YMove = s.y;

	
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);

	线属性.m_YMove = 线属性.m_YScale;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);
}


void f_node_创建立方体虚拟体(S_物体* ob) {
	S_MeshTranformProp 线属性 = f_init_MeshTranform();

	auto indirect中心 = 中心_立方体Indirect;
	S_VkDrawIndirectCommand indirect边界 = {};
	S_VkDrawIndirectCommand indirect方向 = {};

	f_node_设置立方体虚拟体绘制(indirect中心, indirect边界, indirect方向, ob->m_实例ID);
	f_surface_add间接绘制(中心圆, indirect中心);
	f_surface_add间接绘制(边界线, indirect边界);
	f_surface_add间接绘制(方向线, indirect方向);
	ob->m_PickIndirect = indirect中心;


	线属性.m_TransformMode = 0;
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	线属性.m_TransformMode = 0;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);
}

void f_node_设置立方体虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心_立方体Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = {};
	方向线间接 = {};
}

void f_node_设置立方体虚拟网格(S_物体* ob, const vec3& size) {
	S_MeshTranformProp 线属性 = f_init_MeshTranform();

	线属性.m_XScale = size.x;
	线属性.m_YScale = size.y;
	线属性.m_ZScale = size.z;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

	auto indirect中心 = 中心_立方体Indirect;
	S_VkDrawIndirectCommand indirect边界 = {};
	S_VkDrawIndirectCommand indirect方向 = {};

	f_node_设置立方体虚拟体绘制(indirect中心, indirect边界, indirect方向, ob->m_实例ID);
	ob->m_PickIndirect = 中心_立方体Indirect;

	f_surface_set间接绘制区间(中心圆, indirect中心, ob->m_实例ID);
	f_surface_set间接绘制区间(边界线, indirect边界, ob->m_实例ID);
	f_surface_set间接绘制区间(方向线, indirect方向, ob->m_实例ID);

	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);
}

void f_node_设置球体虚拟网格(S_物体* ob, const vec3& size) {
	S_MeshTranformProp 线属性 = f_init_MeshTranform();

	线属性.m_XScale = size.x;
	线属性.m_YScale = size.y;
	线属性.m_ZScale = size.z;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;

	f_surface_set间接绘制区间(中心圆, XYZ圆形Indirect, ob->m_实例ID);
	f_surface_set间接绘制区间(边界线, {}, ob->m_实例ID);
	f_surface_set间接绘制区间(方向线, {}, ob->m_实例ID);

	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);
	f_mesh_set网格元素绘制属性(边界线, 线属性, ob->m_实例ID);
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);
}

void f_node_设置链接线方体虚拟网格(S_物体* ob, const vec3& size, const vec3& loc) {
	S_MeshTranformProp 线属性 = f_init_MeshTranform();

	线属性 = f_buf_网格元素变换属性_at(中心圆->m_网格元素变换属性, ob->m_实例ID);
	线属性.m_XScale = size.x;
	线属性.m_YScale = size.y;
	线属性.m_ZScale = size.z;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom;
	f_mesh_set网格元素绘制属性(中心圆, 线属性, ob->m_实例ID);


	线属性 = f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID);
	线属性.m_XScale = 1;
	线属性.m_YScale = 1;
	线属性.m_ZScale = 1;
	线属性.m_XMove = loc.x;
	线属性.m_YMove = loc.y;
	线属性.m_ZMove = loc.z;
	//线属性.m_DottedLine;
	线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_PointLink;
	f_mesh_set网格元素绘制属性(方向线, 线属性, ob->m_实例ID);


	f_surface_set间接绘制区间(中心圆, 中心_立方体Indirect, ob->m_实例ID);
	f_surface_set间接绘制区间(边界线, {}, ob->m_实例ID);
	f_surface_set间接绘制区间(方向线, 方向线_链接线_Indirect, ob->m_实例ID);
	
}


void f_node_移除虚拟体(S_物体* ob) {
	uint32 num = g虚拟体主物体->m_子物体.size();
	auto* data = g虚拟体主物体->m_子物体.data();

	f_buf_Indirect_at(*中心圆->m_间接, ob->m_实例ID).instanceCount = 0;
	f_buf_Indirect_at(*边界线->m_间接, ob->m_实例ID).instanceCount = 0;
	f_buf_Indirect_at(*方向线->m_间接, ob->m_实例ID).instanceCount = 0;

	ob->m_显示 = false;
	ob->m_渲染 = false;
	ob->m_销毁 = true;
	
	for (uint32 i = 0; i < num; ++i) {
		if (data[i] == ob) {
			g虚拟体主物体->m_子物体.erase(g虚拟体主物体->m_子物体.begin() + i);
			f_surface_mov绘制区间(中心圆, i);
			f_surface_mov绘制区间(边界线, i);
			f_surface_mov绘制区间(方向线, i);
			break;
		}
	}
	
	if(!中心圆->m_间接->m_Mem.m_数量 || !边界线->m_间接->m_Mem.m_数量 || !方向线->m_间接->m_Mem.m_数量) return;

	num = g虚拟体主物体->m_子物体.size();
	data = g虚拟体主物体->m_子物体.data();

	auto* 中心圆indirect = f_buf_Indirect_ptr(*中心圆->m_间接);
	auto* 边界线indirect = f_buf_Indirect_ptr(*边界线->m_间接);
	auto* 方向线indirect = f_buf_Indirect_ptr(*方向线->m_间接);
	for (uint32 i = 0; i < num; ++i) {
		auto* so = (S_物体*)(data[i]);
		so->m_实例ID = i;

		switch (so->m_Type) {
		case E_物体类型::t_点光源: {
			f_node_设置点光源虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_聚光灯: {
			f_node_设置聚光灯虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_区域光_圆形: {
			f_node_设置圆形区域光虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_区域光_方形: {
			f_node_设置方形区域光虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			break;
		}
		case E_物体类型::t_虚拟体: {
			f_node_设置摄像机虚拟体绘制(中心圆indirect[i], 边界线indirect[i], 方向线indirect[i], i);
			so->m_PickIndirect = 中心圆indirect[i];
			break;
		}
		}
	}
}

void f_node_设置灯光虚拟网格类型(S_物体* ob, E_物体类型 类型) {
	switch (类型) {
	case E_物体类型::t_区域光_方形: {
		auto indirect = 四边Indirect;
		indirect.firstInstance = ob->m_实例ID;

		f_surface_set间接绘制区间(边界线, indirect, ob->m_实例ID);
		break;
	}
	case E_物体类型::t_区域光_圆形: {
		auto indirect = XZ圆形Indirect;
		indirect.firstInstance = ob->m_实例ID;
		f_surface_set间接绘制区间(边界线, indirect, ob->m_实例ID);
		break;
	}
	default:
		break;
	}
}

void f_node_设置灯光虚拟网格范围(S_物体* ob, const vec2& r) {
	switch (ob->m_Type) {
	case E_物体类型::t_聚光灯: {
		S_MeshTranformProp 线属性 = f_init_MeshTranform();
		线属性.m_Remote = 1;
		线属性.m_Scale = r.y;
		线属性.m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;

		f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE;
		f_buf_网格元素变换属性_at(方向线->m_网格元素变换属性, ob->m_实例ID).m_Scale = r.y;
		break;
	}
	case E_物体类型::t_区域光_方形: {
		
		break;
	}
	case E_物体类型::t_区域光_圆形: {
		
		break;
	}
	}
}

void f_node_设置点光源虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;
	
	边界线间接 = XYZ圆形Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 方向Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置聚光灯虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = XZ缩放圆形Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 锥形Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置方形区域光虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = 四边Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 方向Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置圆形区域光虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心Indirect;
	中心圆间接.firstInstance = offset;

	边界线间接 = XZ圆形Indirect;
	边界线间接.firstInstance = offset;

	方向线间接 = 方向Indirect;
	方向线间接.firstInstance = offset;
}

void f_node_设置摄像机虚拟体绘制(S_VkDrawIndirectCommand& 中心圆间接, S_VkDrawIndirectCommand& 边界线间接, S_VkDrawIndirectCommand& 方向线间接, uint32 offset) {
	中心圆间接 = 中心_摄像机锥形Indirect;
	中心圆间接.firstInstance = offset;
	
	边界线间接 = 边界线_XY四边形Indirect;
	边界线间接.firstInstance = offset;
	边界线间接.instanceCount = 0;

	方向线间接 = 方向线_Y三角箭头_Indirect;
	方向线间接.firstInstance = offset;
}






S_物体* f_node_创建UV辅助操作虚拟体(S_设备环境& ctx) {
	auto* 虚拟体根物体 = f_node_get单元素虚拟体根物体(&ctx);
	
	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_虚拟体);
	S_Mesh* me = f_surface_创建实例(g单元素虚拟体网格);
	f_ob_set数据槽数量(ob, 1);
	f_ob_set数据(ob, me);
	f_ob_add实例物体(虚拟体根物体, ob);


	f_mesh_计算包围盒(me, gIndirect单元素虚拟体_圆柱.firstVertex, gIndirect单元素虚拟体_圆柱.vertexCount);


	auto indirect = gIndirect单元素虚拟体_圆柱;
	indirect.firstInstance = ob->m_变换ID;
	me->m_间接绘制偏移 = f_surface_add间接绘制(g单元素虚拟体网格, indirect);
	me->m_间接绘制数量 = 1;

	//f_material_add线属性(f_NodeCtx_get单元素虚拟体材质(ctx), 1);
	//S_MeshTranformProp 线属性 = f_init_MeshTranform();
	//f_mesh_set网格元素绘制属性(g单元素虚拟体网格, 线属性, ob->m_实例ID);
	return ob;
}

void f_node_设置UV操作虚拟体类型(S_物体* ob, uint32 type) {
	switch (type) {
	case 0: {
		auto indirect = gIndirect单元素虚拟体_平面;
		indirect.firstInstance = ob->m_变换ID;
		f_surface_set间接绘制区间(g单元素虚拟体网格, indirect, ob->m_实例ID);
		S_MeshTranformProp 线属性 = f_init_MeshTranform();
		f_mesh_set网格元素绘制属性(g单元素虚拟体网格, 线属性, ob->m_实例ID);
		break;
	}
	case 1: {
	//	break;
	}
	case 2: {
	//	break;
	}
	case 3: {
		auto indirect = gIndirect单元素虚拟体_圆柱;
		indirect.firstInstance = ob->m_变换ID;
		f_surface_set间接绘制区间(g单元素虚拟体网格, indirect, ob->m_实例ID);
		S_MeshTranformProp 线属性 = f_init_MeshTranform();
		f_mesh_set网格元素绘制属性(g单元素虚拟体网格, 线属性, ob->m_实例ID);
		break;
	}
	default:
		break;
	}
}

S_物体* f_node_创建单元素虚拟体(S_设备环境& ctx) {
	auto* 虚拟体根物体 = f_node_get多元素虚拟体根物体(ctx);

	S_物体* ob = f_ob_创建(ctx, E_物体类型::t_虚拟体);
	f_ob_add子物体(虚拟体根物体, ob);
	f_buf_push_back<Mat44f>(虚拟体根物体->m_变换矩阵, { {} });
	f_ob_set数据槽数量(虚拟体根物体, 3);

	auto indirect = g虚拟体中心Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(g虚拟体中心圆, indirect);

	indirect = g虚拟体边界线_并排线Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(g虚拟体边界线, indirect);

	indirect = g虚拟体方向Indirect;
	indirect.firstInstance = ob->m_实例ID;
	f_surface_add间接绘制(g虚拟体方向线, indirect);

	return ob;
}
void f_node_设置单元素虚拟体类型(S_物体* ob, uint32 type) {

}

S_物体* f_node_创建圆柱UV辅助操作虚拟体(S_设备环境& ctx) {
	S_物体* m_Ob = f_ob_创建(ctx, E_物体类型::t_虚拟体);
	f_ob_add子物体(g虚拟体主物体, m_Ob);
	f_buf_push_back<Mat44f>(g虚拟体主物体->m_变换矩阵, { {} });
	
	S_MeshTranformProp 线属性 = f_init_MeshTranform();
	
	auto indirect = 中心Indirect;
	indirect.firstInstance = m_Ob->m_实例ID;
	f_surface_add间接绘制(中心圆, indirect);

	indirect = 边界线_并排线Indirect;
	indirect.firstInstance = m_Ob->m_实例ID;
	f_surface_add间接绘制(边界线, indirect);

	indirect = 方向Indirect;
	indirect.firstInstance = m_Ob->m_实例ID;
	f_surface_add间接绘制(方向线, indirect);

	return m_Ob;
}




S_物体* f_node_创建圆柱封套虚拟体(S_设备环境& ctx) {
	S_物体* m_Ob = f_ob_创建(ctx, E_物体类型::t_虚拟体);
	
	m_Ob->m_Name = u"圆柱封套";
	m_Ob->m_视口显示模式 = 0xffffffff;

	uint32 槽数量 = 5;
	f_ob_set数据槽数量(m_Ob, 槽数量);

	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_胶囊封套端, true, true, true, true, true, true), 0);
	f_ob_set材质(m_Ob, f_NodeCtx_get索引绘制_颜色线材质(), 0);
	
	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_胶囊封套端, true, true, true, true, true, true), 1);
	f_ob_set材质(m_Ob, f_NodeCtx_get索引绘制_颜色线材质(), 1);
	

	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_胶囊封套端, true, true, true, true, true, true), 2);
	f_ob_set材质(m_Ob, f_NodeCtx_get索引绘制_颜色线材质(), 2);
	
	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_胶囊封套端, true, true, true, true, true, true), 3);
	f_ob_set材质(m_Ob, f_NodeCtx_get索引绘制_颜色线材质(), 3);
	


	S_Mesh* me = f_surface_创建网格对象(nullptr, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	f_surface_Copy(me, S_节点数据::g_me_胶囊封套管);
	f_ob_set数据(m_Ob, me, 4);
	f_ob_set材质(m_Ob, f_NodeCtx_get索引绘制_颜色线材质(true), 4);
	
	
	
	for (uint32 i = 0; i < 槽数量; ++i) {
		f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, i);
		f_mesh_gen网格元素绘制属性(f_ob_getMesh(m_Ob, i), 1);

		f_mesh_计算包围盒(f_ob_getMesh(m_Ob, i));
		f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, i), {});
		f_ob_set线宽(m_Ob, 1.0, i);
	}
	

	m_Ob->m_可拾取 = false;
	m_Ob->m_显示 = false;

	return m_Ob;
}




void f_node_修改物体名称(S_物体* ob, const S_Props& name) {
	//ob->m_Name = S_节点数据::g_物体名称分配器.f_Gen(f_prop_LineStr(name));
}




std::u16string f_node_物体名称修改(S_Object* ob, const std::u16string& name) {
	
	//if (S_节点数据::g_全局索引物体.find(ob->m_Name) != S_节点数据::g_全局索引物体.end()) {
	//	S_节点数据::g_全局索引物体.erase(ob->m_Name);
	//
	//	S_节点数据::g_物体名称分配器.f_Move(ob->m_Name);
	//}

	//auto newName = S_节点数据::g_物体名称分配器.f_Gen(name);
	//ob->m_Name = newName;
	//S_节点数据::g_全局索引物体[ob->m_Name] = ob;
	return ob->m_Name;
}

void f_node_物体添加到全局容器(S_Object* ob, bool 自动重命名) {
	
	//if (S_节点数据::g_全局索引物体.find(ob->m_Name) != S_节点数据::g_全局索引物体.end()) {
	//	if (S_节点数据::g_全局索引物体[ob->m_Name] == ob) {
	//		//S_节点数据::g_全局索引物体.erase(ob->m_Name);
	//		return;
	//	}
	//}
	//
	//ob->m_Name = S_节点数据::g_物体名称分配器.f_Gen(ob->m_Name);
	//
	//S_节点数据::g_全局索引物体[ob->m_Name] = ob;
	//
	//if (!ob->m_父物体) {
	//	for (auto& e : S_节点数据::g_大纲数据->m_子物体) {
	//		if (e == ob) {
	//			return;
	//		}
	//	}
	//
	//	S_节点数据::g_大纲数据->m_子物体.push_back(ob);
	//}
	//
	//S_物体* 可编辑物体 = dynamic_cast<S_物体*>(ob);
	//if (可编辑物体) {
	//	f_OE_创建可编辑物体属性(可编辑物体);
	//}
}

void f_node_从全局容器移除物体(S_物体* ob) {
	//if (S_节点数据::g_全局索引物体.find(ob->m_Name) != S_节点数据::g_全局索引物体.end()) {
	//	S_节点数据::g_全局索引物体.erase(ob->m_Name);
	//	S_节点数据::g_物体名称分配器.f_Move(ob->m_Name);
	//
	//	//for(auto& e : ob->m_子物体) f_node_从全局容器移除物体((S_物体*)e);
	//
	//	for (auto it = S_节点数据::g_大纲数据->m_子物体.begin(); it != S_节点数据::g_大纲数据->m_子物体.end(); ++it) {
	//		if (*it == ob) {
	//			S_节点数据::g_大纲数据->m_子物体.erase(it);
	//			return;
	//		}
	//	}
	//	//for (auto& e : S_节点数据::g_大纲数据->m_子物体) {
	//	//	if (e == ob) {
	//	//		S_节点数据::g_大纲数据->m_子物体.erase(e);
	//	//		return;
	//	//	}
	//	//}
	//}
}

S_物体* f_node_从全局物体容器查找物体(std::u16string name) {
	//if (S_节点数据::g_全局索引物体.find(name) != S_节点数据::g_全局索引物体.end()) {
	//	S_Object* ob = S_节点数据::g_全局索引物体[name];
	//	return dynamic_cast<S_物体*>(ob);
	//}
	return nullptr;
}



static S_Object* f_node_移除渲染世界(const std::u16string& name) {
	S_Object* world = S_节点数据::g_渲染世界数据[name];

	S_节点数据::g_渲染世界数据.erase(name);
	S_节点数据::g_渲染世界名称分配器.f_Move(name);

	return world;
}

S_Object* f_node_创建渲染世界(std::u16string name, S_设备环境& ctx) {
	S_Object* item = new S_Object(E_物体类型::t_渲染世界);
	item->m_Name = S_节点数据::g_渲染世界名称分配器.f_Gen(name);
	item->m_UserData = f_world_创建渲染世界(ctx);
	item->m_是否展开 = true;

	S_节点数据::g_渲染世界数据[item->m_Name] = item;
	S_节点数据::g_渲染层大纲数据->m_子物体.emplace_back(item);
	return item;
}

S_Object* f_node_删除渲染世界(const std::u16string& name) {
	for (auto it = S_节点数据::g_渲染层大纲数据->m_子物体.begin(); it != S_节点数据::g_渲染层大纲数据->m_子物体.end(); ++it) {
		if ((*it)->m_Name == name) {
			S_节点数据::g_渲染层大纲数据->m_子物体.erase(it);
			return f_node_移除渲染世界(name);
		}
	}
	return nullptr;
}


static S_Object* f_node_移除渲染层(const std::u16string& name) {
	auto* 层 = S_节点数据::g_渲染层数据[name];

	S_节点数据::g_渲染层数据.erase(name);

	S_节点数据::g_渲染层名称分配器.f_Move(name);
	S_节点数据::g_渲染层ID生成器.f_Move(层->m_ID);

	层->m_父对象 = nullptr;
	return 层;
}

S_Object* f_node_创建渲染层(S_Object* 世界, std::u16string name, S_设备环境& ctx) {
	
	S_Object* item = new S_Object(E_物体类型::t_渲染层);
	item->m_Name = S_节点数据::g_渲染层名称分配器.f_Gen(name);
	item->m_ID = S_节点数据::g_渲染层ID生成器.f_Gen();
	item->m_UserData = f_ob_创建渲染层(ctx);
	item->m_是否展开 = true;

	S_节点数据::g_渲染层数据[item->m_Name] = item;
	世界->m_子物体.emplace_back(item);
	item->m_父对象 = 世界;
	return item;
}

S_Object* f_node_删除渲染层(S_Object* 世界, const std::u16string& name) {
	for (auto it = 世界->m_子物体.begin(); it != 世界->m_子物体.end(); ++it) {
		if ((*it)->m_Name == name) {
			世界->m_子物体.erase(it);
			return f_node_移除渲染层(name);
		}
	}
	return nullptr;
}



void f_node_物体添加到渲染层(S_Object* 层, S_物体* ob) {
	for (auto it = 层->m_子物体.begin(); it != 层->m_子物体.end(); ++it) {
		if (*it == ob) {
			return;
		}
	}

	层->m_子物体.emplace_back(ob);
}

void f_node_物体从渲染层移除(S_Object* 层, S_物体* ob) {
	for (auto it = 层->m_子物体.begin(); it != 层->m_子物体.end(); ++it) {
		if (*it == ob) {
			层->m_子物体.erase(it);
			return;
		}
	}
}

void f_node_销毁所有渲染世界() {
	for (auto& e : S_节点数据::g_渲染世界数据) {
		for (auto& 层 : e.second->m_子物体) {
			S_Object* 层对象 = f_node_移除渲染层(层->m_Name);
			delete 层对象;
		}
		e.second->m_子物体.clear();

		S_Object* world = f_node_移除渲染世界(e.first);

		delete world;
	}

	S_节点数据::g_渲染世界数据.clear();
}







S_单色材质包 f_node_get骨骼可视材质(S_设备环境& ctx) {
	S_单色材质包 包;

	if (g_骨骼材质包.size()) {
		包 = g_骨骼材质包.back();
		g_骨骼材质包.pop_back();
	}
	else {
		static S_单色材质包 m = {
			new S_独立缩放单色材质(ctx, E_绘制方式::e_三角形, E_填充模式::e_填充线, true, true, true),
			new S_独立缩放单色材质(ctx, E_绘制方式::e_三角形, E_填充模式::e_填充面, true, true, true),
			new S_独立缩放单色材质(ctx, E_绘制方式::e_三角形, E_填充模式::e_填充线, true, true, true),
		};

		包.m_描边 = (S_单色材质*)m.m_描边->f_copy();
		包.m_面 = (S_单色材质*)m.m_面->f_copy();
		包.m_线 = (S_单色材质*)m.m_线->f_copy();
	}
	
	return 包;
}

void f_node_回收骨骼可视材质(S_单色材质包 包) {
	g_骨骼材质包.push_back(包);
}





S_材质管线* f_node_getVecSphere材质(S_设备环境& ctx) {
	S_材质管线* 材质 = new S_VecSphere可视预览材质(ctx);

	if (g_VecSphere质包.size()) {
		材质 = g_VecSphere质包.back();
		g_VecSphere质包.pop_back();
	}
	else {
		材质 = new S_VecSphere可视预览材质(ctx);
	}

	return 材质;
}

void f_node_回收VecSphere可视材质(S_材质管线* 材质) {
	g_VecSphere质包.push_back(材质);
}

S_骨骼插座数据* f_node_创建编辑骨骼() {
	S_骨骼插座数据* b = new S_骨骼插座数据;
	(*b) = {};
	b->m_骨架 = new S_物体(E_物体类型::t_骨骼);
	b->m_骨节 = new S_物体(E_物体类型::t_实例);
	return b;
}


static std::mutex g要删除物体内存锁;
static std::vector<S_物体*> g要删除物体;
void f_node_创建物体(S_OBArray* obs) {

}

void f_node_删除物体(S_OBArray* obs) {
	g要删除物体内存锁.lock();

	f_node_物体从主场景中移除(obs);
	for (uint32 i=0; i<obs->count; ++i) {
		if (obs->ptr_userData[i]) {
			obs->ptr_userData[i]->m_销毁 = true;
			g要删除物体.push_back(obs->ptr_userData[i]);
		}
	}

	g要删除物体内存锁.unlock();

	f_core_array_resize((S_Array*)obs, 0);
}

void f_node_删除物体(std::vector<S_物体*>& obs) {
	g要删除物体内存锁.lock();

	for (auto& ob : obs) {
		ob->m_销毁 = true;
		ob->m_父对象 = nullptr;
		g要删除物体.push_back(ob);
	}

	g要删除物体内存锁.unlock();

	obs.clear();
}

void f_node_删除物体(S_物体* ob) {
	g要删除物体.push_back(ob);
}

bool f_node_销毁物体() {
	if (g要删除物体.size()) {
		g要删除物体内存锁.lock();

		for (auto& e : g要删除物体) {
			switch (e->m_附属类型) {
				case E_物体类型::t_物理力: {
					if(e->m_UserData) free(e->m_UserData);
					break;
				}
				default:
					break;
			}
			f_ob_销毁(e);
		}
		g要删除物体.clear();

		g要删除物体内存锁.unlock();
		return true;
	}
	
	return false;
}

S_着色器创建配置 f_node_轮廓线管配置(E_几何着色类型 着色面类型) {
	S_着色器创建配置 图元配置;
	图元配置.m_Paths.push_back({ S_引擎配置::m_3D着色器文件根路径 + "物理光照_顶点阶段.spv", {}, E_着色阶段::e_顶点着色 });
	图元配置.m_Paths.push_back({ S_引擎配置::m_3D着色器文件根路径 + "物理光照_片源阶段.spv", {}, E_着色阶段::e_像素着色 });

	图元配置.m_参数布局 = {
			{ 0, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
			{ 1, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO },
			//{ 2, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO },		//灯光方向
			{ DEF_BINDING_WIDGET_Color, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO },

			{ DEF_BINDING_Bones_Props, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_Bones_Map, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_Bones_Matrix, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO },

			{ DEF_BINDING_LineProp, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO },

			//{ DEF_TasterTexturesBindID_rgba32f, E_着色阶段::e_计算着色, E_板载缓存类型::e_SAMPLER_Array},
			{ DEF_BINDING_Render_GlobalParam, E_着色阶段::e_几何着色 | E_着色阶段::e_像素着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_ObMesh, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_TasterBindID_Face, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_TasterBindID_TexCoord, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_TasterBindID_TexIndex, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_Face_AttrIndex, E_着色阶段::e_顶点着色 | E_着色阶段::e_几何着色 | E_着色阶段::e_像素着色, E_板载缓存类型::e_SSBO },
			{ DEF_BINDING_Material_AttrIndex, E_着色阶段::e_顶点着色 | E_着色阶段::e_几何着色 | E_着色阶段::e_像素着色, E_板载缓存类型::e_SSBO },

			{ DEF_MaterialsBindID, E_着色阶段::e_像素着色, E_板载缓存类型::e_SSBO },
			{ DEF_TasterTexturesBindID_rgba8, E_着色阶段::e_像素着色, E_板载缓存类型::e_SAMPLER_Array},

			{ DEF_TasterTexturesBindID_rgba32ui, E_着色阶段::e_像素着色, E_板载缓存类型::e_SSBO},
			{ DEF_TasterTexturesBindID_r32ui, E_着色阶段::e_像素着色, E_板载缓存类型::e_IMAGE},
			{ DEF_TasterBindID_AlphaListCount, E_着色阶段::e_像素着色, E_板载缓存类型::e_SSBO},
	};

	switch (着色面类型) {
		case E_几何着色类型::e_几何着色_面: {
			图元配置.m_Paths.push_back({ S_引擎配置::m_3D着色器文件根路径 + "物理光照.gspv", {}, E_着色阶段::e_几何着色 });
			break;
		}
		case E_几何着色类型::e_几何着色_边: {
			图元配置.m_参数布局.push_back({ DEF_BINDING_Face_AdjacencyID_BindID, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO });
			图元配置.m_参数布局.push_back({ DEF_BINDING_Face_Normal_BindID, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO });
			图元配置.m_参数布局.push_back({ DEF_BINDING_Face_Center_BindID, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO });

			图元配置.m_Paths.push_back({ S_引擎配置::m_3D着色器文件根路径 + "物理光照轮廓.gspv", {}, E_着色阶段::e_几何着色 });
			break;
		}
		case E_几何着色类型::e_几何着色_线: {
			图元配置.m_Paths.push_back({ S_引擎配置::m_3D着色器文件根路径 + "物理光照线.gspv", {}, E_着色阶段::e_几何着色 });
			break;
		}
		default:
			break;
	}
	

	图元配置.m_顶点配置 = {
		{0,sizeof(vec3),0,E_数据格式::e_F_RGB},
		{0,sizeof(vec3),0,E_数据格式::e_F_RGB},
		{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
	};

	图元配置.m_常量偏移和字节数 = { { E_着色阶段::e_顶点着色, 0, sizeof(S_Vert_MeshDrawProp) } };


	return 图元配置;
}






//void f_node_物体节点创建物体数据(S_物体* ob) {
//	f_ob_set数据槽数量(ob, 3);
//
//	S_Mesh* mesh = (S_Mesh*)(ob->m_几何体[0]);
//	S_Mesh* m1 = f_surface_创建实例(mesh);
//	S_Mesh* m2 = f_surface_创建实例(mesh);
//
//	f_ob_set数据(ob, m1, 1);
//	f_ob_set数据(ob, m2, 2);
//
//	f_ob_set材质(ob, f_NodeCtx_get基本光照描边材质(), 0);
//	f_ob_set材质(ob, f_NodeCtx_get基本光照面材质(), 1);
//	f_ob_set材质(ob, f_NodeCtx_get基本光照线材质(), 2);
//
//
//	f_mesh_add网格属性(mesh, 1);
//	f_mesh_add网格属性(m1, 1);
//	f_mesh_add网格属性(m2, 1);
//
//	auto 网格属性 = MeshProp_Init();
//	网格属性.m_Activate = 1;
//	f_mesh_set网格属性(mesh, 网格属性);
//
//	f_node_网格绘制属性设置(ob);
//
//
//	ob->m_Name = L"物体节点创建物体";
//}



//S_物体* f_node_创建多边形物体数据(S_设备环境& ctx) {
//	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_多边形);
//	S_多边形* 多边形 = f_surface_创建多边形();
//	ob->m_UserData = 多边形;
//
//	ob->m_Name = L"多边形";
//	
//	f_node_构建多边形网格对象(ctx, ob);
//
//	f_NodeCtx_get默认场景()->f_add物体({ ob }, E_场景物体容器类型::e_集合);
//	return ob;
//}


//void f_创建网格物体组(std::vector<S_物体*>& 物体, uint32 num, S_设备环境& ctx) {
//	uint32 old_num = 物体.size();
//	auto* r = 物体.data();
//
//	r = 物体.data();
//	for (uint32 i = num; i < old_num; ++i) {
//		f_NodeCtx_get默认场景()->f_remove物体(r[i], E_场景物体容器类型::e_集合);
//		f_ob_销毁(r[i]);
//	}
//
//	物体.resize(num);
//	r = 物体.data();
//
//	for (uint32 i = 0; i < num; ++i) {
//		if (r[i] == 0) {
//			//r[i] = f_ob_创建物体(E_物体类型::t_网格, 0, ctx);
//			r[i] = f_node_网格节点创建物体数据(ctx);
//		}
//	}
//}




/*S_物体* f_node_创建点光源虚拟网格(S_设备环境& ctx) {

	static S_Mesh* 外圆圈线 = nullptr;
	static S_Mesh* 竖向线 = nullptr;


	if (!g圆圈线) {
		g圆圈线 = f_创建圆圈线(ctx);

		std::vector<S_VC> 顶点;
		std::vector<vec2> 圆顶点(20);

		外圆圈线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		外圆圈线->m_网格类型 = E_绘制方式::e_画线段;
		外圆圈线->m_线宽 = 0.1;

		圆顶点.resize(40);
		顶点.clear();
		f_graph_计算圆坐标XY({}, 1.0, 40, 圆顶点.data());
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,128}) });
		}
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, f_PackData4X8(S_RGBA8UI{0,0,0,128}) });
		}
		for (auto& e : 圆顶点) {
			顶点.push_back({ {0, e.y, e.x}, f_PackData4X8(S_RGBA8UI{0,0,0,128}) });
		}
		f_surface_fill顶点数据(外圆圈线, 顶点);
		f_surface_计算包围盒(外圆圈线);
	}

	if (!竖向线) {
		竖向线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
		竖向线->m_网格类型 = E_绘制方式::e_画线段;
		竖向线->m_线宽 = 0.7;

		std::vector<S_VC> 顶点;
		顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
		f_surface_fill顶点数据(竖向线, 顶点);
		f_surface_计算包围盒(竖向线);

	}

	static S_物体* 点光源主物体 = nullptr;
	if (!点光源主物体) {
		点光源主物体 = f_ob_创建物体(ctx, E_物体类型::t_包);

		f_ob_set数据槽数量(点光源主物体, 3);

		f_ob_set数据(点光源主物体, g圆圈线, 0);
		f_ob_set数据(点光源主物体, 外圆圈线, 1);
		f_ob_set数据(点光源主物体, 竖向线, 2);
		f_ob_set材质(点光源主物体, f_NodeCtx_get逐顶点线段材质(true), 0);
		f_ob_set材质(点光源主物体, f_NodeCtx_get逐顶点线段材质(), 1);
		f_ob_set材质(点光源主物体, f_NodeCtx_get逐顶点线段材质(), 2);



		f_NodeCtx_get默认场景()->f_add物体({ 点光源主物体 }, E_场景物体容器类型::e_集合);
	}


	S_LinesProp 线属性;
	线属性.m_DottedLine = 1;
	线属性.m_Remote = 0;
	线属性.m_Scale = 1;
	线属性.m_TransformMode = 1;

	S_物体* m_Ob = f_ob_创建物体(ctx, E_物体类型::t_点光源);
	m_Ob->m_ID = f_scene_渲染器分配点光源内存(f_NodeCtx_get默认场景());

	f_material_add线属性(f_NodeCtx_get逐顶点线段材质(true), 1);
	f_material_set线属性(f_NodeCtx_get逐顶点线段材质(true), m_Ob->m_ID, 线属性);

	线属性.m_TransformMode = 0;
	f_material_add线属性(f_NodeCtx_get逐顶点线段材质(), 1);
	f_material_set线属性(f_NodeCtx_get逐顶点线段材质(), m_Ob->m_ID, 线属性);
	f_ob_add子物体(点光源主物体, m_Ob);

	return m_Ob;
}

S_物体* f_node_创建平行光虚拟网格(S_设备环境& ctx) {
	S_Mesh* 圆圈线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	圆圈线->m_网格类型 = E_绘制方式::e_画线段;

	S_Mesh* 方向线 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	方向线->m_网格类型 = E_绘制方式::e_画线段;


	std::vector<S_VC> 顶点;
	顶点.push_back({ {0,0,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
	顶点.push_back({ {0,-1,0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
	f_surface_fill顶点数据(方向线, 顶点);
	//f_graph_构建骨骼锥体(size, V, N, I);
	顶点.clear();

	std::vector<vec2> 圆顶点(20);
	f_graph_计算圆坐标XY({}, 0.2, 20, 圆顶点.data());
	顶点.reserve(20);
	for (auto& e : 圆顶点) {
		顶点.push_back({ {e.x, e.y, 0}, f_PackData4X8(S_RGBA8UI{0,0,0,255}) });
	}
	f_surface_fill顶点数据(圆圈线, 顶点);



	圆圈线->m_线宽 = 1.0;
	方向线->m_线宽 = 3.0;


	S_物体* ob = f_ob_创建物体(ctx, E_物体类型::t_线段);
	f_ob_创建矩阵(ob, ctx);
	f_ob_set数据槽数量(ob, 2);
	f_ob_set数据(ob, 圆圈线, 0);
	f_ob_set数据(ob, 方向线, 1);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 0);
	f_ob_set材质(ob, f_NodeCtx_get逐顶点线段材质(), 1);
	return ob;
}*/

//S_物体* f_node_创建骨架物体(S_设备环境& ctx) {
//
//	S_物体* 骨架对象 = f_ob_创建物体(ctx, E_物体类型::t_物体包);
//	//S_物体* 虚线 = f_node_创建虚线(ctx);
//	{
//		S_物体* 骨骼物体 = f_ob_创建物体(ctx, E_物体类型::t_骨架);
//		S_物体* 骨节物体 = f_ob_创建物体(ctx, E_物体类型::t_网格);
//
//		f_ob_create骨骼虚拟体网格(ctx, 骨骼物体, 骨节物体);
//		f_node_将现有物体包装成骨骼网格(ctx, 骨骼物体, 骨节物体);
//
//		f_ob_add子物体(骨架对象, 骨骼物体);
//		f_ob_add子物体(骨架对象, 骨节物体);
//		//f_ob_add子物体(m_骨骼对象, m_虚线);
//
//		S_物体* 根骨节 = f_ob_创建物体实例(nullptr, 0);
//		根骨节->m_UserData = 骨骼物体;
//		f_ob_add子物体(骨节物体, 根骨节);
//		
//		骨骼物体->m_UserData = 根骨节;
//	}
//	return 骨架对象;
//}

//S_物体* f_node_创建骨头物体(S_设备环境& ctx) {
//	S_物体* 骨头 = f_ob_创建骨骼(nullptr);
//
//	S_物体* 骨节 = f_ob_创建物体实例(nullptr, 0);
//	骨节->f_set位置(DEF_骨骼朝向, 0);
//	骨头->m_UserData = 骨节;
//
//	return 骨头;
//}
